package com.yanqu.road.server.channelserver.manager.activity;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.activityunion.ActivityUnionInfo;
import com.yanqu.road.entity.activity.activityunion.ActivityUnionMemberInfo;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.logic.pb.UnionBasePb;
import com.yanqu.road.logic.rank.UnionRankMsgModel;
import com.yanqu.road.pb.rank.RankProto;
import com.yanqu.road.pb.union.cross.CrossUnionProto;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.channelserver.manager.activity.tonbing.ChannelTonBingMgr;
import com.yanqu.road.server.channelserver.manager.activity.tonbing.activity.ChannelTonBingActivity;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 所有活动的商会的需要的赚钱
 * */
public class ChannelActivityUnionMgr extends TempMgr {

    //每个渠道拉取总长度的商会数
    //活动id 渠道id 商会id 商会信息
    private static Map<Integer,Map<Integer, Map<String, ActivityUnionInfo>>> acUnionInfoMap  = new ConcurrentHashMap<>();

    private static Map<Integer, UnionRankMsgModel> unionRankMsgModelMap  = new ConcurrentHashMap<>();


    private static Map<Integer,Long> updateChannelServerTimeMap = new ConcurrentHashMap<>();
    //channelId serverId
    private static Map<Integer,List<Long>> channelServerIdList = new ConcurrentHashMap<>();

    //商会变动锁住
    private static Map<Integer,Object> lockMap = new ConcurrentHashMap<>();

    private static Object getLock(int activityId){
        if(!lockMap.containsKey(activityId)){
            synchronized (lockMap){
                if(!lockMap.containsKey(activityId)){
                    lockMap.put(activityId,new Object());
                }
            }
        }
        return lockMap.get(activityId);
    }

    public static int getUnionChannel(int activityId,String unionId){
        if(acUnionInfoMap.containsKey(activityId)){
            Map<Integer, Map<String, ActivityUnionInfo>> channelUnionMap = acUnionInfoMap.get(activityId);
            for(int channelId : channelUnionMap.keySet()){
                if(channelUnionMap.get(channelId).containsKey(unionId)){
                    return channelId;
                }
            }
        }
        return 0;
    }

    public static UnionRankMsgModel getUnionRankMsgModel(int activityId) {
        ActivityInfo activityInfo = ChannelActivityInfoMgr.getActivityInfo(activityId);
        if (null == activityInfo) {
            return null;
        }
        UnionRankMsgModel model = unionRankMsgModelMap.get(activityId);
        if (null == model) {
            synchronized (unionRankMsgModelMap) {
                model = unionRankMsgModelMap.get(activityId);
                if (null == model) {
                    model = new UnionRankMsgModel(0, activityId, activityInfo.getEndShowTime());
                    model.setRankListMsg(RankProto.UnionRankListMsg.newBuilder());
                    unionRankMsgModelMap.put(activityId, model);
                }
            }
        }

        long nowTime = System.currentTimeMillis();
        if(nowTime - model.getUpdateTime() > 10 * DateHelper.SECOND_MILLIONS){
            if(activityInfo.getType() == eActivityType.ChannelTonBingActivity.getValue()){
                ChannelTonBingActivity ca = ChannelTonBingMgr.getActivity(activityId);
                if(ca != null && ca.getConfig() != null){
                    int topNum = ca.getConfig().getUnionChannelNum() + 50;//多弄五十个
                    model.setRankListMsg(getTopChannelMaxAbilityUnionListMsg(activityId,topNum));
                }
            }
            model.setUpdateTime(nowTime);
        }

        return model;
    }

    //拉取所有的排序的
    public static RankProto.UnionRankListMsg.Builder getTopMaxAbilityUnionListMsg(int activityId,int topCount) {
        RankProto.UnionRankListMsg.Builder rankMsg = RankProto.UnionRankListMsg.newBuilder();
        List<ActivityUnionInfo> unionInfos = new ArrayList<>();
        if(!acUnionInfoMap.containsKey(activityId)){
            return rankMsg;
        }
        for(Map<String, ActivityUnionInfo> cAcMap : acUnionInfoMap.get(activityId).values()){
            unionInfos.addAll(cAcMap.values());
        }

        unionInfos.sort((o1, o2) -> {
            return o2.getTotalAbility().compareTo(o1.getTotalAbility());
        });

        for (int i = 0; i < topCount && i < unionInfos.size(); i++) {
            ActivityUnionInfo unionInfo = unionInfos.get(i);
            RankProto.UnionRankTempMsg.Builder tempMsg = RankProto.UnionRankTempMsg.newBuilder();
            tempMsg.setUnionUid(unionInfo.getUnionId());
            tempMsg.setUnionBaseData(UnionBasePb.parseUnionBaseTempMsg(unionInfo.getUnionBaseInfo()));
            tempMsg.setValue(unionInfo.getTotalAbility().toString());
            rankMsg.addRankList(tempMsg);
        }

        return rankMsg;
    }

    //拉取对应渠道前几排名的
    public static RankProto.UnionRankListMsg.Builder getTopChannelMaxAbilityUnionListMsg(int activityId,int channelCount) {
        RankProto.UnionRankListMsg.Builder rankMsg = RankProto.UnionRankListMsg.newBuilder();
        Map<Integer,List<ActivityUnionInfo>> channelUnionInfos = new ConcurrentHashMap<>();
        List<ActivityUnionInfo> allUnions = new ArrayList<>();
        if(!acUnionInfoMap.containsKey(activityId)){
            return rankMsg;
        }
        for(int channelId : acUnionInfoMap.get(activityId).keySet()){
            Map<String, ActivityUnionInfo> cAcMap = acUnionInfoMap.get(activityId).get(channelId);
            channelUnionInfos.put(channelId,new ArrayList<>(cAcMap.values()));
        }

        for(List<ActivityUnionInfo> unionInfos : channelUnionInfos.values()){
            unionInfos.sort((o1, o2) -> {
                return o2.getTotalAbility().compareTo(o1.getTotalAbility());
            });
            for (int i = 0; i < channelCount && i < unionInfos.size(); i++) {
                ActivityUnionInfo unionInfo = unionInfos.get(i);
                allUnions.add(unionInfo);
            }
        }

        allUnions.sort((o1, o2) -> {
            return o2.getTotalAbility().compareTo(o1.getTotalAbility());
        });

        for (int i = 0; i < allUnions.size(); i++) {
            ActivityUnionInfo unionInfo = allUnions.get(i);
            RankProto.UnionRankTempMsg.Builder tempMsg = RankProto.UnionRankTempMsg.newBuilder();
            tempMsg.setUnionUid(unionInfo.getUnionId());
            tempMsg.setUnionBaseData(UnionBasePb.parseUnionBaseTempMsg(unionInfo.getUnionBaseInfo()));
            tempMsg.setValue(unionInfo.getTotalAbility().toString());
            rankMsg.addRankList(tempMsg);
        }

        return rankMsg;
    }

    public static boolean containsActivity(ActivityInfo acInfo){
        List<Integer> channelIdList = StringUtils.stringToIntegerList(acInfo.getParam6(),";");

        //没有这个渠道的记录就都发
        if(!acUnionInfoMap.containsKey(acInfo.getActivityId())){
            return false;
        }
        List<Integer> getChannelIdList = new ArrayList<>(acUnionInfoMap.get(acInfo.getActivityId()).keySet());
        for(int channelId : channelIdList){
            if(!getChannelIdList.contains(channelId)){
                return false;
            }
        }
        return true;
    }

    public static boolean isServerIdInChannel(long serverId,int channelId){
        //没有这个渠道的记录就都发
        if(!channelServerIdList.containsKey(channelId)){
            return true;
        }
        return channelServerIdList.get(channelId).contains(serverId);
    }

    public static boolean isUpdateChanelServer(int channelId){
        long nowTime = System.currentTimeMillis();
        if(updateChannelServerTimeMap.getOrDefault(channelId,0L) + DateHelper.MINUTE_MILLIONS < nowTime){
            return true;
        }
        return false;
    }

    public static void updateChannelServer(CrossUnionProto.ChannelGetUnionMaxAbilityRankListResp respMsg){
        channelServerIdList.put(respMsg.getChannel(),respMsg.getServerIdList());
        updateChannelServerTimeMap.put(respMsg.getChannel(),System.currentTimeMillis());
    }

    public static void addUnionInfo(CrossUnionProto.ChannelGetUnionMaxAbilityRankListResp respMsg){
        int activityId = respMsg.getActivityId();
        synchronized (getLock(activityId)){
            ActivityInfo activityInfo = ChannelActivityInfoMgr.getActivityInfo(activityId);
            if(activityInfo.getType() == eActivityType.ChannelTonBingActivity.getValue()){
                ChannelTonBingActivity ac = ChannelTonBingMgr.getActivity(activityId);
                if(ac != null && ac.getConfig() != null){
                    long overTime = ac.getConfig().getJoinTimeList().get(1) + DateHelper.MINUTE_MILLIONS;
                    if(containsActivity(activityInfo) && System.currentTimeMillis() > overTime && ac.getChannelTonBingDataMain().isLockUnion()){
                        return;
                    }
                }
            }
            int channelId = respMsg.getChannel();
            if(!acUnionInfoMap.containsKey(activityId)){
                acUnionInfoMap.put(activityId,new ConcurrentHashMap<>());
            }
            Map<Integer, Map<String, ActivityUnionInfo>> channelUnionMap = acUnionInfoMap.get(activityId);
            if(!channelUnionMap.containsKey(channelId)){
                channelUnionMap.put(channelId,new ConcurrentHashMap<>());
            }
            Map<String, ActivityUnionInfo> unionMap = channelUnionMap.get(channelId);
            for(CrossUnionProto.ChannelUnionActivityLockRankTemp unionRankMsg : respMsg.getRankList()){
                ActivityUnionInfo activityUnionInfo = null;
                if(unionMap.containsKey(unionRankMsg.getUnionUid())){
                    activityUnionInfo = unionMap.get(unionRankMsg.getUnionUid());
                }else{
                    activityUnionInfo = new ActivityUnionInfo();
                    unionMap.put(unionRankMsg.getUnionUid(),activityUnionInfo);
                }
                activityUnionInfo.setUnionBaseInfo(UnionBasePb.parseUnionBaseInfo(unionRankMsg.getUnionBase()));
                activityUnionInfo.setTotalAbility(new BigInteger(unionRankMsg.getTotalAbility()));
                activityUnionInfo.setUnionId(unionRankMsg.getUnionUid());
            }
            for(CrossUnionProto.ChannelUnionMemberListTemp memberInfoMsg : respMsg.getUnionMembersList()){
                Map<Long, ActivityUnionMemberInfo> memberInfoMap = null;
                ActivityUnionInfo activityUnionInfo = null;
                if(unionMap.containsKey(memberInfoMsg.getUnionId())){
                    activityUnionInfo = unionMap.get(memberInfoMsg.getUnionId());
                    memberInfoMap = activityUnionInfo.getMemberInfoMap();
                }else{
                    activityUnionInfo = new ActivityUnionInfo();
                    memberInfoMap = new ConcurrentHashMap<>();
                    unionMap.put(memberInfoMsg.getUnionId(),activityUnionInfo);
                }
                for(CrossUnionProto.ChannelUnionMemberTemp memberTemp: memberInfoMsg.getMembersList()){
                    if(memberInfoMap.containsKey(memberTemp.getUserId())){
                        ActivityUnionMemberInfo memberInfo = memberInfoMap.get(memberTemp.getUserId());
                        memberInfo.setAbility(new BigInteger(memberTemp.getAbility()));
                        memberInfo.setPosition(memberTemp.getPosition());
                    }else{
                        ActivityUnionMemberInfo memberInfo = new ActivityUnionMemberInfo();
                        memberInfo.setUserId(memberTemp.getUserId());
                        memberInfo.setChannelId(channelId);
                        memberInfo.setServerId(memberTemp.getServerId());
                        memberInfo.setAbility(new BigInteger(memberTemp.getAbility()));
                        memberInfo.setPosition(memberTemp.getPosition());
                        memberInfoMap.put(memberInfo.getUserId(),memberInfo);
                    }
                }
                activityUnionInfo.setMemberInfoMap(memberInfoMap);
            }
            channelServerIdList.put(respMsg.getChannel(),respMsg.getServerIdList());
            updateChannelServerTimeMap.put(respMsg.getChannel(),System.currentTimeMillis());
        }
    }

    public static void tonBingGameStart(int activityId){
        synchronized (getLock(activityId)){
            ActivityInfo activityInfo = ChannelActivityInfoMgr.getActivityInfo(activityId);
            if(containsActivity(activityInfo)){
                RankProto.CrossUnionRankListLockMsg.Builder lockMsg = RankProto.CrossUnionRankListLockMsg.newBuilder();
                lockMsg.setActivityId(activityId);
                LinkedList<ActivityUnionInfo> unionList = new LinkedList<>();
                for(Map<String, ActivityUnionInfo> uMap : acUnionInfoMap.get(activityId).values()){
                    unionList.addAll(uMap.values());
                }
                unionList.sort((o1, o2) -> {
                    return o2.getTotalAbility().compareTo(o1.getTotalAbility());
                });

                for(ActivityUnionInfo activityUnionInfo : unionList){
                    if(StringUtils.isNullOrEmpty(activityUnionInfo.getUnionId())){
                        getLogger().error("出现没有商会id的商会");
                        continue;
                    }
//                        ChannelTonBingRank rank = new ChannelTonBingRank();
//                        rank.setId(activityUnionInfo.getUnionId());
//                        rank.setValue(activityUnionInfo.getTotalAbility().longValue());
//                        rankList.add(rank);
                    RankProto.CrossUnionRankLockTemp.Builder lockTempMsg = RankProto.CrossUnionRankLockTemp.newBuilder();
                    RankProto.UnionRankTempMsg.Builder unionRankTempMsg = RankProto.UnionRankTempMsg.newBuilder();
                    unionRankTempMsg.setUnionUid(activityUnionInfo.getUnionId());
                    unionRankTempMsg.setUnionBaseData(UnionBasePb.parseUnionBaseTempMsg(activityUnionInfo.getUnionBaseInfo()));
                    unionRankTempMsg.setValue(activityUnionInfo.getTotalAbility().toString());
                    lockTempMsg.setRankTemp(unionRankTempMsg);
                    for(ActivityUnionMemberInfo memberInfo : activityUnionInfo.getMemberInfoMap().values()){
                        RankProto.CrossUnionMemberTemp.Builder memMsg = RankProto.CrossUnionMemberTemp.newBuilder();
                        memMsg.setMemberId(memberInfo.getUserId());
                        memMsg.setServerId(memberInfo.getServerId());
                        memMsg.setChannelId(memberInfo.getChannelId());
                        memMsg.setPosition(memberInfo.getPosition());
                        lockTempMsg.addMember(memMsg);
                    }
                    lockMsg.addRank(lockTempMsg);
                }
                //不写了，原来那样吧
                ChannelTonBingActivity ac = ChannelTonBingMgr.getActivity(activityId);
                if(ac != null){
                    ac.lockUnion(lockMsg.build());
                }
            }
        }
    }

    //按照一个渠道一个阵营的版本来的
    public static void tonBingGameStartChannel(int activityId){
        synchronized (getLock(activityId)){
            ActivityInfo activityInfo = ChannelActivityInfoMgr.getActivityInfo(activityId);
            if(containsActivity(activityInfo)){
                Map<Integer,LinkedList<ActivityUnionInfo>> channelUnionMap = new ConcurrentHashMap<>();
                for(int channelId : acUnionInfoMap.get(activityId).keySet()){
                    Map<String, ActivityUnionInfo> uMap = acUnionInfoMap.get(activityId).get(channelId);
                    if(!channelUnionMap.containsKey(channelId)){
                        channelUnionMap.put(channelId,new  LinkedList<>());
                    }
                    channelUnionMap.get(channelId).addAll(uMap.values());
                    channelUnionMap.get(channelId).sort((o1, o2) -> {
                        return o2.getTotalAbility().compareTo(o1.getTotalAbility());
                    });
                }
                //不写了，原来那样吧
                ChannelTonBingActivity ac = ChannelTonBingMgr.getActivity(activityId);
                if(ac != null){
                    ac.lockUnionChannel(channelUnionMap);
                }
            }
        }
    }

    public static int getChannelId(long serverId) {
        for(int channelId : channelServerIdList.keySet()){
            List<Long> serverIdList = channelServerIdList.get(channelId);
            if(serverIdList.contains(serverId)){
                return channelId;
            }
        }
        return 0;
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }
}
